﻿using System;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using IQIGame.Onigao.Framework;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    [ExecuteAlways]
    public class TypewriterText : ExText
    {
        [SerializeField] public float speed = 10;

        [SerializeField] public bool useAutoSize = false;
        [SerializeField] public int fontWidth = 36;
        [SerializeField] public int fontHeight = 45;
        [SerializeField] public int lineFontNum = 25;

        private Tweener _tween;

        private string _targetText;

        private Action _onContentComplete;

        public string targetText
        {
            get => this._targetText;
            set
            {
                var rTarget = value ?? "";
                if (!this.isPlaying || rTarget != this.targetText)
                {
                    this.text = "";
                    this._targetText = rTarget;
                    this._time = 0;

                    if (this.useAutoSize)
                    {
                        var nTxtLen = rTarget.Length;
                        var nWidth = Math.Min(nTxtLen, this.lineFontNum) * this.fontWidth;
                        var nHeight = (nTxtLen / this.lineFontNum + 1) * this.fontHeight;
                        this.rectTransform.sizeDelta = new Vector2(nWidth, nHeight);
                    }
                }
                if (this._unitaskCompletionSource != null)
                {
                    this._unitaskCompletionSource.TrySetResult();
                    this._unitaskCompletionSource = null;
                }
            }
        }

        AutoResetUniTaskCompletionSource _unitaskCompletionSource;

        public UniTask ToUniTask()
        {
            if (this._unitaskCompletionSource != null)
            {
                return this._unitaskCompletionSource.Task;
            }
            this._unitaskCompletionSource = AutoResetUniTaskCompletionSource.Create();
            return this._unitaskCompletionSource.Task;
        }

        public bool isPlaying => !string.IsNullOrEmpty(this.targetText) && this.text != this.targetText;

        public void Skip()
        {
            if (this.isPlaying)
            {
                this.text = this._targetText;
                this._onContentComplete?.Invoke();
            }
            if (this._unitaskCompletionSource != null)
            {
                // 注意！这里要先置空，再调用，TrySetResult会先调用await之后的代码，如果await之后有给TaskSource赋新值，然后这里再置空，那么_completeActTaskSource就永远为null了。
                // 若置空不及时导致了多次source.TrySetResult，会导致池内数据异常
                var rSource = this._unitaskCompletionSource;
                this._unitaskCompletionSource = null;
                rSource.TrySetResult();
            }
        }

        /// <summary>
        /// 注册要在设置信息后，若没有目标认为直接完成放掉
        /// </summary>
        /// <param name="onContentComplete"></param>
        public void RegisterOnContentComplete(Action onContentComplete)
        {
            this._onContentComplete = onContentComplete;
            if (!this.isPlaying)
            {
                this._onContentComplete?.Invoke();
            }
        }

        public void UnRegisterOnContentComplete()
        {
            this._onContentComplete = null;
        }

        private float _time;
        private float fontTime => 1f / this.speed;

        public void OnUpdate(float deltaTime)
        {
            if (!this.isPlaying || string.IsNullOrEmpty(this._targetText))
            {
                return;
            }
            this._time += deltaTime;
            if (this._time < this.fontTime)
            {
                return;
            }
            this._time -= this.fontTime;
            if (this.text.Length < this._targetText.Length - 1)
            {
                var rTextCount = this.text.Length + 1;
                this.text = this._targetText.Substring(0, rTextCount);
            }
            else
            {
                this.Skip();
            }
        }
    }
}